package com.itcs.dubbo.service.impl;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import com.alibaba.fastjson.JSON;
import com.itcs.dubbo.exception.TranBusException;
import com.itcs.dubbo.exception.TranNotFoundException;
import com.itcs.dubbo.service.DubboService;
import com.itcs.dubbo.service.DubboServiceAdapter;

/**
 * dubbo通用接口实现
 * 
 * @author LiuPeng
 * @date 2017年12月9日
 * 
 */
//@Service("itcsApp")//在配置文件里已定义
public class DubboServiceImpl implements DubboService, ApplicationContextAware {

	protected final Log logger = LogFactory.getLog(getClass());

	private Map<String, DubboServiceAdapter> dubboServiceAdapterMap;
	
	@Override
	public Map<String, Object> exchange(String trancode, Map<String, Object> reqRecord) throws Exception {
		logger.info("接收Dubbo请求:" + trancode + "[" + JSON.toJSONString(reqRecord) + "]");

		DubboServiceAdapter dubboServiceAdapter = dubboServiceAdapterMap.get(trancode);
		if (dubboServiceAdapter == null) {
			throw new TranNotFoundException("not found  trancode[" + trancode + "] DubboServiceAdapter");
		}
		Map<String, Object> res = null;
		try {
			res = dubboServiceAdapter.exchange(reqRecord);
		} catch (TranBusException e) {
			logger.error(e.getMessage(), e);
			throw e;
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(trancode + ",请求调用失败:" + e.getMessage(), e);
			throw new TranBusException("999999", trancode + ",请求调用失败:" + e.getMessage());
		}
		return res;
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		initDubboServiceAdapters(applicationContext);
	}

	/**
	 * 初始化dubbo通用接口适配器
	 * 
	 * @param applicationContext
	 */
	private void initDubboServiceAdapters(ApplicationContext applicationContext) {
		if (dubboServiceAdapterMap == null) {
			Map<String, DubboServiceAdapter> beanMap = BeanFactoryUtils
					.beansOfTypeIncludingAncestors(applicationContext, DubboServiceAdapter.class, true, false);
			dubboServiceAdapterMap = new HashMap<>(beanMap.size());
			for (Map.Entry<String, DubboServiceAdapter> entry : beanMap.entrySet()) {
				if (dubboServiceAdapterMap.containsKey(entry.getValue().getTrancode())) {
					throw new RuntimeException(
							"初始化dubbo通用接口适配器失败,trancode[" + entry.getValue().getTrancode() + "] 发现多个适配器");
				} else {
					dubboServiceAdapterMap.put(entry.getValue().getTrancode(), entry.getValue());
				}
			}
			logger.info("初始化dubbo通用接口适配器完成:" + dubboServiceAdapterMap.size());
		}
	}

}
